package cohesion.system.trigger
{
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	import flash.utils.getTimer;

	/**
	 * <dl>
	 *
	 * 	<dt>文件描述:</dt>
	 *		<dd>帧事件触发器，实现flashPlayer失去焦点之后保证自动补帧的功能。该类作为包内封闭类，仅在Trigger中管理</dd>
	 *
	 *	<dt>创建日期:</dt>
	 *		<dd>2012-2-21</dd>
	 *
	 * 	<dt>更新日期:</dt>
	 *		<dd>2012-2-21</dd>
	 *
	 * 	<dt>文件版本:</dt>
	 *		<dd>1.0</dd>
	 *
	 * </dl>
	 *
	 * @see cohesion.system.trigger.Trigger
	 * @author ZQiang张强
	 */
	internal class TriggerTimer
	{
		private static const frameRate:uint = 24;
		private static const halfRate:uint = frameRate >> 1;
		private static const intervalTime:uint = 1000 / frameRate;

		private var useFrame:Boolean;
		private var timers:Dictionary;
		private var deltaTime:Number = 0;
		private var lastTime:uint = 0;
		private var timer:Shape;
		private var myTimer:Timer
		private var preFun:Function;
		private var afterFun:Function;

		public function TriggerTimer(useFrame:Boolean)
		{
			if (useFrame)
			{
				timer = new Shape();
				timer.addEventListener(Event.ENTER_FRAME , enterFrameHandler);
			}
			else
			{
				myTimer = new Timer(intervalTime);
				myTimer.addEventListener(TimerEvent.TIMER , enterFrameHandler);
				myTimer.start();
			}
			this.useFrame = useFrame;
			timers = new Dictionary();
		}

		private function enterFrameHandler(event:Event):void
		{
			var nowTime:uint = getTimer();
			deltaTime = nowTime - lastTime;
			lastTime = nowTime;
			var realFrame:uint = uint(1000 / deltaTime); //上一帧的实际帧频

			if (realFrame >= halfRate)
			{
				loopStart();
				loop();
				loopComplete();
			}
			else
			{
				var tweenFrames:uint = Math.round(frameRate / realFrame);
				for (var i:uint = 0 ; i < tweenFrames ; i++)
				{
					loop();
				}
			}
		}

		private function loopStart():void
		{
			if (preFun != null)
				preFun.call();
		}

		private function loop():void
		{
			for each (var vo:TriggerVO in timers)
			{
				if (vo.trigger())
					delete timers[vo.onUpdate];
			}
		}

		private function loopComplete():void
		{
			if (afterFun != null)
				afterFun.call();
		}

		/**
		 * 通过触发器添加一个帧处理方法
		 * @param delay 多少帧出发一次
		 * @param repeat 重复触发多少次,0为无限触发
		 * @param onUpdate	每次触发时候回调方法
		 * @param onUpdateParams	每次触发时候回调方法参数
		 * @param onComplete 触发结束后回调方法
		 * @param onCompleteParams 触发结束后回调方法参数
		 */
		public function add(delay:int , repeat:int , onUpdate:Function , onUpdateParams:Array = null , onComplete:Function = null , onCompleteParams:Array = null):void
		{
			timers[onUpdate] = new TriggerVO(delay , repeat , onUpdate , onUpdateParams , onComplete , onCompleteParams);
		}

		/**
		 * 移除触发器中某个帧处理方法
		 * @param onUpdate 每次触发时候回调方法
		 *
		 */
		public function remove(onUpdate:Function):void
		{
			timers[onUpdate].release();
			delete timers[onUpdate];
		}

		/**
		 * 执行一次触发，一般用在延迟执行或者倒计时执行
		 * @param delay				延迟多少个单位执行
		 * @param onComplete		回调方法
		 * @param onCompleteParams	回调方法参数
		 *
		 */
		public function singleTrigger(delay:int , onComplete:Function = null , onCompleteParams:Array = null):void
		{
			timers[onComplete] = new TriggerVO(delay , 1 , null , null , onComplete , onCompleteParams);
		}

		/**
		 * 注册在触发前和触发后分别回调的方法
		 * @param preTrigger   触发前回调函数
		 * @param afterTrigger 触发后回调函数
		 *
		 */
		public function registerFunction(preTrigger:Function , afterTrigger:Function):void
		{
			preFun = preTrigger;
			afterFun = afterTrigger;
		}

		/**
		 * 释放这个触发器
		 */
		internal function release():void
		{
			if (useFrame)
			{
				timer.removeEventListener(Event.ENTER_FRAME , enterFrameHandler);
				timer = null;
			}
			else
			{
				myTimer.stop();
				myTimer.removeEventListener(TimerEvent.TIMER , enterFrameHandler);
				myTimer = null;
			}
			for each (var vo:TriggerVO in timers)
				vo.release();

			timers = null;
		}
	}
}